/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bff.core.action.retrievedefault;

import com.inspur.edp.bff.api.dataprocessor.IDefaultValueConvertor;
import com.inspur.edp.bff.api.exception.BffFrameworkException;
import com.inspur.edp.bff.api.exception.ErrorCodes;
import com.inspur.edp.bff.api.manager.IFSManagerContext;
import com.inspur.edp.bff.api.manager.assembler.IAssemblerManager;
import com.inspur.edp.bff.api.manager.context.DataMapperContext;
import com.inspur.edp.bff.api.manager.context.RetrieveDefaultContext;
import com.inspur.edp.bff.entity.defaultvalue.VoDefaultValue;
import com.inspur.edp.bff.spi.AbstractFSAction;
import com.inspur.edp.bff.spi.builtin.BffEntityResInfoImpl;
import com.inspur.edp.bff.spi.builtin.BffModelResInfoImpl;
import com.inspur.edp.bff.spi.builtin.BffPropertyInfo;
import com.inspur.edp.cef.entity.entity.IEntityData;
import com.inspur.edp.cef.spi.entity.info.propertyinfo.DataTypePropertyInfo;
import com.inspur.edp.cef.spi.entity.resourceInfo.ModelResInfo;
import com.inspur.edp.cef.spi.entity.resourceInfo.builinImpls.CefModelResInfoImpl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class RetrieveDefaultAction extends AbstractFSAction<IEntityData> {


    private VoDefaultValue defaultValue;
    private String dataId;

    public RetrieveDefaultAction() {
    }

    public RetrieveDefaultAction(VoDefaultValue defaultValue) {
        this.defaultValue = defaultValue;
    }

    public RetrieveDefaultAction(String dataId) {
        this.dataId = dataId;
    }

    @Override
    protected void execute() {
        IAssemblerManager assemblerManager = getContext().getAssemblerManager();
        if (assemblerManager == null) {
            doDefaultRetrieveDefault();
            return;
        }
        RetrieveDefaultContext createContext = new RetrieveDefaultContext();
        createContext.setVoDefaultValue(defaultValue);
        createContext.setDataId(dataId);
        //① BeforeRetrieve
        assemblerManager.getRetrieveDefaultAssembler().doBeforeRetrieveDefault(getContext(), createContext);

        //② DoRetrieve
        assemblerManager.getRetrieveDefaultAssembler().doRetrieveDefault(getContext(), createContext);
        //③ DataMapping
        DataMapperContext mapperContext = new DataMapperContext();
        mapperContext.setSourceData(createContext.getRetrieveDefaultData());
        mapperContext.setIsNew(true);
        mapperContext.setVoDefaultValue(defaultValue);
        ArrayList<IEntityData> vmDatas = assemblerManager.getDataMapperAssembler().
                doDataMapping2Vo(getContext(), mapperContext);

        //处理虚拟字段默认值
        if (getModelInfo() instanceof BffModelResInfoImpl) {
            dealVirtualDefaultValue(vmDatas.get(0), getContext());
        }
        createContext.setRetrieveDefaultResult(vmDatas.get(0));
        //④ AfterRetrieve
        assemblerManager.getRetrieveDefaultAssembler().doAfterRetrieveDefault(getContext(), createContext);

        if (vmDatas == null || vmDatas.size() == 0) {
            throw new BffFrameworkException(ErrorCodes.BFF_FRAMEWORK_1017);
        }
        setResult(vmDatas.get(0));
    }

    private ModelResInfo getModelInfo() {
        return this.getContext().getModelResourceInfo();
    }

    private void dealVirtualDefaultValue(IEntityData data, IFSManagerContext context) {
        ModelResInfo modelResInfo = context.getModelResourceInfo();
        if (modelResInfo != null && modelResInfo instanceof CefModelResInfoImpl) {
            BffEntityResInfoImpl resInfo = (BffEntityResInfoImpl) modelResInfo.getCustomResource(modelResInfo.getRootNodeCode());
            Map<String, DataTypePropertyInfo> propertyInfos = resInfo.getEntityTypeInfo().getPropertyInfos();
            if (propertyInfos == null || propertyInfos.size() == 0)
                return;
            dealDefalutValue(propertyInfos, data);
        }
    }

    private void dealDefalutValue(Map<String, DataTypePropertyInfo> propertyInfos, IEntityData data) {
        for (Map.Entry<String, DataTypePropertyInfo> propInfo : propertyInfos.entrySet()) {
            String beLabelId = ((BffPropertyInfo) (propInfo.getValue())).getBeLabelId();
            if (beLabelId != null && !"".equals(beLabelId))
                continue;
            if ((propInfo.getValue()).getDefaultValue() != null) {
                data.setValue((propInfo.getValue()).getPropertyName(), (propInfo.getValue()).getDefaultValue().getRealValue());
            }

        }
    }

    private void doDefaultRetrieveDefault() {
        IEntityData beData;

        IDefaultValueConvertor convertor = getContext().getDefaultValueConvertor();
        if (defaultValue != null && convertor != null) {

            HashMap<String, Object> beDefault = convertor.convertFromVo(defaultValue);
            beData = getLcp().retrieveDefault(beDefault);
        } else if (!(dataId == null || dataId.isEmpty())) {
            beData = getLcp().retrieveDefault(dataId);
        } else {
            beData = getLcp().retrieveDefault();
        }

        IEntityData vmData = getContext().createData();
        getContext().getDataConvertor().convertFromBEData(beData, vmData);
        setResult(vmData);
    }

}
